package com.sc.nft.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalException;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.CopyrightAuctionService;
import com.sc.nft.service.EquityPropsService;
import com.sc.nft.service.NftRegionBindingService;
import com.sc.nft.service.UserEquityPropsService;
import com.sc.nft.util.BigDecimalUtils;
import com.sc.nft.util.OrderNoUtil;
import com.sc.nft.util.WeChatUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 版权拍卖商品 服务实现类
 * </p>
 *
 * @author liGen
 * @since 2024-09-12
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CopyrightAuctionServiceImpl implements CopyrightAuctionService {
    private final CopyrightAuctionDao copyrightAuctionDao;
    private final CopyrightAuctionConfigDao copyrightAuctionConfigDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final UserCollectionDao userCollectionDao;
    private final CopyrightAuctionRecordDao copyrightAuctionRecordDao;
    private final CopyrightAuctionRoundDao copyrightAuctionRoundDao;
    private final StaticDataDao staticDataDao;
    private final CatenaInfoDao catenaInfoDao;
    private final UserCreatorInfoDao userCreatorInfoDao;
    private final UserEquityPropsService userEquityPropsService;
    private final EquityPropsService equityPropsService;
    private final CopyrightAuctionUserBiddingDao copyrightAuctionUserBiddingDao;
    private final CopyrightAuctionUserBiddingLogDao copyrightAuctionUserBiddingLogDao;
    private final CopyrightAuctionUserBiddingDetailDao copyrightAuctionUserBiddingDetailDao;
    private final NftRegionBindingService nftRegionBindingService;
    private final CopyrightAuctionUserAgreementDao copyrightAuctionUserAgreementDao;
    private final CopyrightAuctionDividedLogDao copyrightAuctionDividedLogDao;

    private final Redisson redisson;

    /**
     * 版权藏品拍卖里列表接口
     *
     * @param name
     * @param mp
     * @return
     */
    @Override
    public IPage<CopyrightAuctionAdminPageVO> collectionPage(String name, Page mp) {
        IPage<CopyrightAuctionAdminPageVO> copyrightAuctionAdminPageVOIPage = copyrightAuctionDao.collectionPage(name, mp);
        if (Objects.nonNull(copyrightAuctionAdminPageVOIPage) && !CollectionUtils.isEmpty(copyrightAuctionAdminPageVOIPage.getRecords())) {
            for (CopyrightAuctionAdminPageVO record : copyrightAuctionAdminPageVOIPage.getRecords()) {
                record.setCurrentPrice(record.getInitialStartPrice());
                CopyrightAuctionRecord newOneByCopyrightAuctionId = copyrightAuctionRecordDao.getNewOneByCopyrightAuctionId(record.getId());
                if (Objects.nonNull(newOneByCopyrightAuctionId)) {
                    record.setCurrentPrice(newOneByCopyrightAuctionId.getStartPrice());
                }
            }
        }
        return copyrightAuctionAdminPageVOIPage;
    }

    /**
     * 版权藏品拍卖添加接口
     *
     * @param copyrightAuctionAdminDTO
     */
    @Override
    public void collectionAdd(CopyrightAuctionAdminDTO copyrightAuctionAdminDTO) {
        if (copyrightAuctionAdminDTO.getStartPrice() < 1) {
            throw new GlobalRunTimeException("起拍价需大于1");
        }
        DigitalCollection collection = digitalCollectionDao.getById(copyrightAuctionAdminDTO.getCollectionId());
        if (Objects.isNull(collection)) {
            throw new GlobalRunTimeException("藏品不存在");
        }
        CopyrightAuction copyrightAuction = copyrightAuctionDao.getByCollectionId(copyrightAuctionAdminDTO.getCollectionId());
        if (Objects.nonNull(copyrightAuction)) {
            throw new GlobalRunTimeException("已绑定该藏品");
        }
        CopyrightAuction saveCopyAuction = new CopyrightAuction();
        saveCopyAuction.setCollectionId(copyrightAuctionAdminDTO.getCollectionId());
        saveCopyAuction.setStatus(Boolean.FALSE);
        saveCopyAuction.setStartPrice(copyrightAuctionAdminDTO.getStartPrice());
        saveCopyAuction.setInitialStartPrice(copyrightAuctionAdminDTO.getStartPrice());
        copyrightAuctionDao.save(saveCopyAuction);
    }

    /**
     * 拍卖配置修改
     *
     * @param configAdminDTO
     */
    @Override
    public void configSave(CopyrightAuctionConfigAdminDTO configAdminDTO) {
//        //判断拍卖开始时间至终止时间是否合法
//        Date auctionStartTime = configAdminDTO.getAuctionStartTime();
//        Date auctionEndTime = configAdminDTO.getAuctionEndTime();
//        //轮次
//        Integer round = configAdminDTO.getRound();
//        //单轮持续时间
//        Integer singleRoundTime = configAdminDTO.getSingleRoundTime();
//        //轮次间隔时间
//        Integer roundIntervalTime = configAdminDTO.getRoundIntervalTime();
//        if (Objects.nonNull(auctionStartTime) && Objects.nonNull(auctionEndTime) && auctionStartTime.after(auctionEndTime)) {
//            throw new GlobalRunTimeException("拍卖开始时间不能大于或等于拍卖结束时间");
//        }
//        //判断开始时间至结束时间是否等于 (轮次 * 单轮持续时间) + (轮次间隔时间 * (轮次 - 1))
//        if (Objects.nonNull(auctionStartTime) && Objects.nonNull(auctionEndTime) && Objects.nonNull(round) && Objects.nonNull(singleRoundTime) && Objects.nonNull(roundIntervalTime)) {
//            long totalTime = (long) round * singleRoundTime + (long) roundIntervalTime * (round - 1);
//            long startTime = auctionStartTime.getTime();
//            long endTime = auctionEndTime.getTime();
//            if (startTime + totalTime != endTime) {
//                throw new GlobalRunTimeException("拍卖开始时间至终止时间不等于 (轮次 * 单轮持续时间) + (轮次间隔时间 * (轮次 - 1))");
//            }
//        }
        if (configAdminDTO.getId() != null) {
            CopyrightAuctionConfig copyrightAuctionConfig = copyrightAuctionConfigDao.getById(configAdminDTO.getId());
            if (Objects.nonNull(copyrightAuctionConfig)) {
                BeanUtils.copyProperties(configAdminDTO, copyrightAuctionConfig);
                copyrightAuctionConfigDao.updateById(copyrightAuctionConfig);
                return;
            }
            copyrightAuctionConfig = new CopyrightAuctionConfig();
            BeanUtils.copyProperties(configAdminDTO, copyrightAuctionConfig);
            copyrightAuctionConfig.setId(null);
            copyrightAuctionConfigDao.save(copyrightAuctionConfig);
            return;
        }
        CopyrightAuctionConfig copyrightAuctionConfig = new CopyrightAuctionConfig();
        BeanUtils.copyProperties(configAdminDTO, copyrightAuctionConfig);
        copyrightAuctionConfigDao.save(copyrightAuctionConfig);
    }


    /**
     * 拍卖配置详情
     *
     * @return
     */
    @Override
    public CopyrightAuctionConfigAdminVO configDetail() {
        CopyrightAuctionConfig copyrightAuctionConfig = copyrightAuctionConfigDao.getNewOne();
        CopyrightAuctionConfigAdminVO copyrightAuctionConfigAdminVO = new CopyrightAuctionConfigAdminVO();
        if (Objects.nonNull(copyrightAuctionConfig)) {
            BeanUtils.copyProperties(copyrightAuctionConfig, copyrightAuctionConfigAdminVO);
        }
        return copyrightAuctionConfigAdminVO;
    }

    /**
     * 版权藏品拍卖按钮
     *
     * @param copyrightAuctionAdminDTO
     */
    @Override
    public void collectionUpdateStatus(CopyrightAuctionUpdateStatusAdminDTO copyrightAuctionAdminDTO) {
        CopyrightAuction copyrightAuction = copyrightAuctionDao.getById(copyrightAuctionAdminDTO.getId());
        if (Objects.isNull(copyrightAuction)) {
            throw new GlobalRunTimeException("拍卖不存在");
        }
        Assert.isTrue(
                copyrightAuctionDao.updateStatus(copyrightAuctionAdminDTO.getId(), copyrightAuctionAdminDTO.getStatus()), () -> new GlobalRunTimeException("操作失败,请稍后重试!"));

    }


    /**
     * 报名竞拍活动获取信息
     *
     * @param user
     * @param userCollectionId
     * @return
     */
    @Override
    public CopyrightAuctionRegistrationDetailsVO registrationDetails(UserInfo user, Long userCollectionId) {
        UserCollection userCollection = userCollectionDao.getByUserIdAndUserCollectionId(user.getId(), userCollectionId);
        Assert.notNull(userCollection, () -> new GlobalRunTimeException("藏品不存在"));
        //判断是否绑定地图
        Boolean nftBinding = nftRegionBindingService.getNftBinding(userCollection.getCollectionId());
        if (!nftBinding) {
            throw new GlobalRunTimeException("藏品权益未生效,请联系客服");
        }
        Date nftEffectiveTime = nftRegionBindingService.getNftEffectiveTime(userCollection.getCollectionId());
        Boolean equityInEffect = Boolean.FALSE;
        if (Objects.nonNull(nftEffectiveTime) && nftEffectiveTime.after(new Date())) {
            equityInEffect = Boolean.TRUE;
        }

        Assert.isFalse(equityInEffect, () -> new GlobalRunTimeException("权益生效中无法报名"));

        CopyrightAuction byCollectionId = copyrightAuctionDao.getByCollectionId(userCollection.getCollectionId());
        Assert.isTrue(byCollectionId.getStatus(), () -> new GlobalRunTimeException("活动未开启"));

        CopyrightAuctionRegistrationDetailsVO copyrightAuctionRegistrationDetailsVO = new CopyrightAuctionRegistrationDetailsVO();
        StaticData scrollPropsId = staticDataDao.getByType("scroll_props_id");
        Long equityId = Long.parseLong(scrollPropsId.getValue());
        EquityProps equityProps = equityPropsService.getById(equityId);
        copyrightAuctionRegistrationDetailsVO.setStartFirstTitle(equityProps.getFirstTitle());
        CopyrightAuctionConfig copyrightAuctionConfig = copyrightAuctionConfigDao.getNewOne();

        //查询最近一次的拍卖记录
//        CopyrightAuctionRecord newOne = copyrightAuctionRecordDao.getNewOne(userCollection.getCollectionId());
        copyrightAuctionRegistrationDetailsVO.setBuyPrice(byCollectionId.getStartPrice());
        copyrightAuctionRegistrationDetailsVO.setStartPrice(byCollectionId.getStartPrice());

        copyrightAuctionRegistrationDetailsVO.setCustomStartPriceAmplitude(copyrightAuctionConfig.getCustomStartPriceAmplitude());


        //查询今日是否有拍卖
        CopyrightAuctionRecord todayRecode = copyrightAuctionRecordDao.getByCollectionAndToday(userCollection.getCollectionId());
        //明天是否有拍卖记录
        CopyrightAuctionRecord nextDayRecord = copyrightAuctionRecordDao.getByCollectionAndTomorrow(userCollection.getCollectionId());
        //每日开始时间 格式是HH:mm:ss
        Date auctionStartTime = copyrightAuctionConfig.getAuctionStartTime();
        //每日结束时间 格式是HH:mm:ss
        Date auctionEndTime = copyrightAuctionConfig.getAuctionEndTime();
        //将每日开始时间和结束时间转成今日yyyy-MM-dd HH:mm:ss格式的
        Date date = new Date();
        String today = DateUtil.format(date, "yyyy-MM-dd");
        String startTime = today + " " + DateUtil.format(auctionStartTime, "HH:mm:ss");
        DateTime todayStartTime = DateUtil.parse(startTime);

        String endTime = today + " " + DateUtil.format(auctionEndTime, "HH:mm:ss");
        DateTime todayEndTime = DateUtil.parse(endTime);
        //今天时间 -1小时
        DateTime dateTime = DateUtil.offsetHour(todayStartTime, -1);
        //今天没拍卖
        StringBuilder stringBuilder = new StringBuilder();
        if (Objects.isNull(todayRecode) || todayRecode.getHaveResult()) {
            //判断今天是否可以报名
            if (date.before(dateTime)) {
                stringBuilder.append(today).append(" ").append(DateUtil.format(auctionStartTime, "HH:mm")).append("-").append(DateUtil.format(auctionEndTime, "HH:mm"));
                copyrightAuctionRegistrationDetailsVO.setButtonStatus(AcutionRegistrationEnum.REGISTRATION);
            } else {
                //明天存在记录就是修改、不存在就是报名拍卖
                stringBuilder.append(DateUtil.format(DateUtil.offsetDay(date, 1), "yyyy-MM-dd")).append(" ").append(DateUtil.format(auctionStartTime, "HH:mm")).append("-").append(DateUtil.format(auctionEndTime, "HH:mm"));
                if (Objects.nonNull(nextDayRecord)) {
                    copyrightAuctionRegistrationDetailsVO.setButtonStatus(AcutionRegistrationEnum.ADDITIONAL);
                    copyrightAuctionRegistrationDetailsVO.setAuctionId(nextDayRecord.getId());
                    copyrightAuctionRegistrationDetailsVO.setStartPrice(nextDayRecord.getStartPrice());
                } else {
                    copyrightAuctionRegistrationDetailsVO.setButtonStatus(AcutionRegistrationEnum.REGISTRATION);
                }
            }
        } else {
            if (date.before(dateTime)) {
                copyrightAuctionRegistrationDetailsVO.setAuctionId(todayRecode.getId());
                copyrightAuctionRegistrationDetailsVO.setStartPrice(todayRecode.getStartPrice());
                copyrightAuctionRegistrationDetailsVO.setButtonStatus(AcutionRegistrationEnum.ADDITIONAL);
                stringBuilder.append(DateUtil.format(date, "yyyy-MM-dd")).append(" ").append(DateUtil.format(auctionStartTime, "HH:mm")).append("-").append(DateUtil.format(auctionEndTime, "HH:mm"));
            } else {
                throw new GlobalRunTimeException("离开始时间不足一小时无法操作");
            }
            if (DateUtil.isIn(date, todayStartTime, todayEndTime)) {
                throw new GlobalRunTimeException("活动进行中无法操作");
            }
        }
        copyrightAuctionRegistrationDetailsVO.setAuctionTime(stringBuilder.toString());
        return copyrightAuctionRegistrationDetailsVO;
    }

    /**
     * 报名活动或修改起拍价
     *
     * @param user
     * @param registrationDTO
     * @return
     */
    @Override
    public void registration(UserInfo user, CopyrightAuctionRegistrationDTO registrationDTO) {
        UserCollection userCollection = userCollectionDao.getByUserIdAndUserCollectionId(user.getId(), registrationDTO.getId());
        Assert.notNull(userCollection, () -> new GlobalRunTimeException("藏品不存在"));
        CopyrightAuction copyrightAuction = copyrightAuctionDao.getByCollectionId(userCollection.getCollectionId());
        //查询配置
        CopyrightAuctionConfig copyrightAuctionConfig = copyrightAuctionConfigDao.getNewOne();
        Assert.isTrue(copyrightAuction.getStatus(), () -> new GlobalRunTimeException("活动未开启"));
        //传入的价格
        Integer dtoStartPrice = registrationDTO.getStartPrice();
        //上一次的成交价
        Integer startPrice = copyrightAuction.getStartPrice();
        //自定义加价幅度
        Integer customStartPriceAmplitude = copyrightAuctionConfig.getCustomStartPriceAmplitude();
        //判断传入的价格是否在上一次的成交价基础上加减自定义加价幅度之间
        Assert.isTrue(dtoStartPrice >= startPrice - customStartPriceAmplitude && dtoStartPrice <= startPrice + customStartPriceAmplitude, () -> new GlobalRunTimeException("起拍价不在范围内"));
        if (null != registrationDTO.getAuctionId() && registrationDTO.getAuctionId() > 0) {
            //修改起拍价
            CopyrightAuctionRecord copyrightAuctionRecord = copyrightAuctionRecordDao.getById(registrationDTO.getAuctionId());
            Assert.notNull(copyrightAuctionRecord, () -> new GlobalRunTimeException("竞拍活动不存在"));
            //判断是否是开始时间前一个小时
            Date date = new Date();
            if (!date.before(DateUtil.offsetHour(copyrightAuctionRecord.getAuctionStartTime(), -1))) {
                throw new GlobalRunTimeException("离竞拍不足一小时无法修改起拍价");
            }
            Assert.isTrue(copyrightAuctionRecordDao.updateStartPrice(copyrightAuctionRecord.getId(), registrationDTO.getStartPrice()), () -> new GlobalRunTimeException("修改起拍价失败,请稍后重试!"));
        } else {
            if (userCollection.getFreezingStatus() != UserCollectionFreezingStatusEnum.NORMAL) {
                throw new GlobalRunTimeException("藏品状态不正确");
            }
            //锁定藏品
            Assert.isTrue(userCollectionDao.updateFreezingStatusById(registrationDTO.getId(), UserCollectionFreezingStatusEnum.LOCK), () -> new GlobalRunTimeException("锁定藏品失败"));
            Date nftEffectiveTime = nftRegionBindingService.getNftEffectiveTime(userCollection.getCollectionId());
            Boolean equityInEffect = Boolean.FALSE;
            if (Objects.nonNull(nftEffectiveTime) && nftEffectiveTime.after(new Date())) {
                equityInEffect = Boolean.TRUE;
            }
            //报名 1.判断是否权益生效中，2.判断是否已经
            if (equityInEffect) {
                throw new GlobalRunTimeException("权益生效中无法报名");
            }
            CopyrightAuctionRecord newOneByCopyrightAuctionId = copyrightAuctionRecordDao.getNewOneByCopyrightAuctionId(userCollection.getCollectionId());
            if (Objects.nonNull(newOneByCopyrightAuctionId) && !newOneByCopyrightAuctionId.getHaveResult()) {
                throw new GlobalRunTimeException("已存在报名信息无法重复报名");
            }
            //查询今日是否有拍卖
            CopyrightAuctionRecord todayRecode = copyrightAuctionRecordDao.getByCollectionAndToday(userCollection.getCollectionId());
            //明天拍卖的记录
            CopyrightAuctionRecord nextDayRecord = copyrightAuctionRecordDao.getByCollectionAndTomorrow(userCollection.getCollectionId());
            //每日开始时间 格式是HH:mm:ss
            Date auctionStartTime = copyrightAuctionConfig.getAuctionStartTime();
            //每日结束时间 格式是HH:mm:ss
            Date auctionEndTime = copyrightAuctionConfig.getAuctionEndTime();
            //将每日开始时间和结束时间转成今日yyyy-MM-dd HH:mm:ss格式的
            Date date = new Date();
            String today = DateUtil.format(date, "yyyy-MM-dd");
            String startTime = today + " " + DateUtil.format(auctionStartTime, "HH:mm:ss");
            DateTime todayStartTime = DateUtil.parse(startTime);

            String endTime = today + " " + DateUtil.format(auctionEndTime, "HH:mm:ss");
            DateTime todayEndTime = DateUtil.parse(endTime);
            //是否可以报名
            Boolean canRegistration = Boolean.FALSE;
            //是否报名今日
            Boolean isToday = Boolean.FALSE;
            //今天时间 -1小时
            DateTime dateTime = DateUtil.offsetHour(todayStartTime, -1);
            //今天没拍卖
            if (Objects.isNull(todayRecode) || todayRecode.getHaveResult()) {
                //判断当前时间是否是每日开始时间之前1小时
                if (date.before(dateTime)) {
                    canRegistration = Boolean.TRUE;
                    isToday = Boolean.TRUE;
                } else {
                    //明天不存在就是报名拍卖
                    if (Objects.isNull(nextDayRecord)) {
                        canRegistration = Boolean.TRUE;
                        isToday = Boolean.FALSE;
                    }
                }
            }
            if (!canRegistration) {
                throw new GlobalRunTimeException("已报名无法重复报名");
            }
            CopyrightAuctionRecord copyrightAuctionRecord = new CopyrightAuctionRecord();
            if (isToday) {
                //今天
                copyrightAuctionRecord.setAuctionStartTime(todayStartTime);
                copyrightAuctionRecord.setAuctionEndTime(todayEndTime);
            } else {
                //明天
                String tomorrow = DateUtil.format(DateUtil.offsetDay(date, 1), "yyyy-MM-dd");
                String tomorrowStartTime = tomorrow + " " + DateUtil.format(auctionStartTime, "HH:mm:ss");
                DateTime tomorrowStartDate = DateUtil.parse(tomorrowStartTime);

                String tomorrowEndTime = tomorrow + " " + DateUtil.format(auctionEndTime, "HH:mm:ss");
                DateTime tomorrowEndDate = DateUtil.parse(tomorrowEndTime);

                copyrightAuctionRecord.setAuctionStartTime(tomorrowStartDate);
                copyrightAuctionRecord.setAuctionEndTime(tomorrowEndDate);
            }
            copyrightAuctionRecord.setCopyrightAuctionId(copyrightAuction.getId());
            copyrightAuctionRecord.setCollectionId(userCollection.getCollectionId());
            copyrightAuctionRecord.setUserCollectionId(userCollection.getId());
            copyrightAuctionRecord.setStartPrice(registrationDTO.getStartPrice());
            copyrightAuctionRecord.setUserId(user.getId());
            copyrightAuctionRecord.setHaveResult(Boolean.FALSE);
            Assert.isTrue(copyrightAuctionRecordDao.save(copyrightAuctionRecord), () -> new GlobalRunTimeException("报名失败,请稍后重试!"));
            //单轮持续时间
            Integer singleRoundTime = copyrightAuctionConfig.getSingleRoundTime();
            //轮次间隔时间
            Integer roundIntervalTime = copyrightAuctionConfig.getRoundIntervalTime();
            //轮次
            Integer round = copyrightAuctionConfig.getRound();
            List<CopyrightAuctionRound> copyrightAuctionRoundList = new ArrayList<>();
            //上一轮的结束时间
            Date lastRoundEndTime = null;

            for (Integer i = 0; i < round; i++) {
                CopyrightAuctionRound copyrightAuctionRound = new CopyrightAuctionRound();
                copyrightAuctionRound.setCopyrightAuctionId(copyrightAuction.getId());
                copyrightAuctionRound.setCopyrightAuctionRecordId(copyrightAuctionRecord.getId());
                copyrightAuctionRound.setRound(i + 1);
                //如果是第一轮
                if (i == 0) {
                    copyrightAuctionRound.setRoundStartTime(copyrightAuctionRecord.getAuctionStartTime());
                    copyrightAuctionRound.setRoundEndTime(DateUtil.offsetMinute(copyrightAuctionRecord.getAuctionStartTime(), singleRoundTime));
                    lastRoundEndTime = copyrightAuctionRound.getRoundEndTime();
                } else if (i == round - 1) {
                    //是最后一轮
                    copyrightAuctionRound.setRoundStartTime(DateUtil.offsetMinute(lastRoundEndTime, roundIntervalTime));
                    copyrightAuctionRound.setRoundEndTime(DateUtil.offsetMinute(copyrightAuctionRound.getRoundStartTime(), singleRoundTime));
                } else {
                    //中间轮开始时间是上一轮结束时间+间隔时间
                    copyrightAuctionRound.setRoundStartTime(DateUtil.offsetMinute(lastRoundEndTime, roundIntervalTime));
                    //中间轮结束时间是当前开始键+单轮持续时间
                    copyrightAuctionRound.setRoundEndTime(DateUtil.offsetMinute(copyrightAuctionRound.getRoundStartTime(), singleRoundTime));
                    lastRoundEndTime = copyrightAuctionRound.getRoundEndTime();
                }
                copyrightAuctionRoundList.add(copyrightAuctionRound);
            }
            //需要写入的轮次和轮数不一致
            if (copyrightAuctionRoundList.size() != round) {
                throw new GlobalRunTimeException("报名失败,请稍后重试!");
            }
            Assert.isTrue(copyrightAuctionRoundDao.saveBatch(copyrightAuctionRoundList), () -> new GlobalRunTimeException("报名失败,请稍后重试!"));


        }

    }


    /**
     * 市场版权商品
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public IPage<CopyrightMarketAuctionDTO> market(Integer pageNo, Integer pageSize) {
        IPage<CopyrightMarketAuctionDTO> auctionDTOIPage = copyrightAuctionRecordDao.market(pageNo, pageSize, null);
        if (Objects.nonNull(auctionDTOIPage) && !CollectionUtils.isEmpty(auctionDTOIPage.getRecords())) {
            CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
            StaticData scrollPropsId = staticDataDao.getByType("scroll_props_id");
            Long equityId = Long.parseLong(scrollPropsId.getValue());
            EquityProps equityProps = equityPropsService.getById(equityId);
            for (CopyrightMarketAuctionDTO record : auctionDTOIPage.getRecords()) {
                record.setStartFirstTitle(equityProps.getFirstTitle());
                if (record.getProsperityDecimal() == null) {
                    record.setProsperity("0.0");
                    continue;
                }
                record.setProsperityDecimal(auctionConfig.getProsperityRate().multiply(record.getProsperityDecimal()).setScale(1, RoundingMode.DOWN));
                //如果record.Prosperity 大于一万，则显示万元
                if (record.getProsperityDecimal().compareTo(new BigDecimal("10000")) > 0) {
                    record.setProsperityDecimal(record.getProsperityDecimal().divide(new BigDecimal("10000"), 1, RoundingMode.DOWN));
                    record.setProsperity(record.getProsperityDecimal() + "万");
                } else {
                    record.setProsperity(record.getProsperityDecimal() + "");
                }
            }
        }
        return auctionDTOIPage;
    }


    /**
     * 市场版权拍卖商品详情
     *
     * @param id
     * @param user
     * @return
     */
    @Override
    public CopyrightMarketAuctionDetailsVO marketDetails(Long id, UserInfo user) {
        Date date = new Date();
        CopyrightAuctionRecord copyrightAuctionRecord = copyrightAuctionRecordDao.getById(id);
        Assert.notNull(copyrightAuctionRecord, () -> new GlobalRunTimeException("拍卖活动不存在"));
        CopyrightAuction copyrightAuction = copyrightAuctionDao.getByCollectionId(copyrightAuctionRecord.getCollectionId());
        Assert.notNull(copyrightAuction, () -> new GlobalRunTimeException("拍卖活动不存在"));
        Assert.isTrue(copyrightAuction.getStatus(), () -> new GlobalRunTimeException("拍卖活动未开启"));
        DigitalCollection digitalCollection = digitalCollectionDao.getById(copyrightAuctionRecord.getCollectionId());
        CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
        CopyrightMarketAuctionDetailsVO detailsVO = new CopyrightMarketAuctionDetailsVO();
        detailsVO.setAuctionStartTime(copyrightAuctionRecord.getAuctionStartTime());
        detailsVO.setAuctionEndTime(copyrightAuctionRecord.getAuctionEndTime());
        detailsVO.setFirstTitle(digitalCollection.getFirstTitle());
        detailsVO.setSumCount(digitalCollection.getSumCount());
        detailsVO.setProductDetailPicture(digitalCollection.getProductDetailPicture());
        detailsVO.setProductDetailPictureType(digitalCollection.getProductDetailPictureType());
        detailsVO.setProductPresentation(digitalCollection.getProductPresentation());
        UserCreatorInfo userCreatorInfo = userCreatorInfoDao.getById(digitalCollection.getUserCreatorId());
        detailsVO.setNickName(userCreatorInfo.getDaoName());
        detailsVO.setCreatorAvatarImg(userCreatorInfo.getCreatorAvatarImg());
        StaticData staticData = staticDataDao.getByType("purchase_notes");
        detailsVO.setPurchaseNotes(staticData.getValue());
        StaticData copyrightPurchaseNotice = staticDataDao.getByType("copyright_purchase_notice");
        if (Objects.nonNull(copyrightPurchaseNotice)) {
            detailsVO.setCopyrightPurchaseNotice(copyrightPurchaseNotice.getValue());
        }
        CatenaInfo catenaInfo = catenaInfoDao.getById(digitalCollection.getCatenaId());
        detailsVO.setCatenaName(catenaInfo.getName());
        String privilegePresentation = digitalCollection.getPrivilegePresentation();
        if (ObjectUtil.isEmpty(privilegePresentation)) {
            privilegePresentation = "";
        }
        detailsVO.setPrivilegePresentation(privilegePresentation);
        detailsVO.setNowDate(DateUtil.now());
        detailsVO.setThreeModelId(digitalCollection.getThreeModelId());
        detailsVO.setCreationContent(digitalCollection.getCreationContent());
        detailsVO.setModelImg(digitalCollection.getModelImg());
        detailsVO.setModelDistance(digitalCollection.getModelDistance());
        detailsVO.setRuleImg(auctionConfig.getRuleImg());
        List<CopyrightAuctionRound> roundList = copyrightAuctionRoundDao.listByCopyrightAuctionRecordId(copyrightAuctionRecord.getId());
        //起拍价 判断是否roundList中的roundStartTime是否在区间
        StaticData scrollPropsId = staticDataDao.getByType("scroll_props_id");
        Long equityId = Long.parseLong(scrollPropsId.getValue());
        EquityProps equityProps = equityPropsService.getById(equityId);
        detailsVO.setStartFirstTitle(equityProps.getFirstTitle());
        detailsVO.setPriceAmplitude(auctionConfig.getPriceAmplitude());
        detailsVO.setOwnedCount(userEquityPropsService.getHavingCountByUserId(equityId, user.getId()));
        List<CopyrightMarketAuctionFlowDTO> copyrightMarketAuctionFlowDTOS = new ArrayList<>();
        Boolean isInRound = Boolean.FALSE;
        Long roundId = 0L;
        detailsVO.setStartPrice(copyrightAuctionRecord.getStartPrice());
        for (int i = 0; i < roundList.size(); i++) {
            CopyrightAuctionRound copyrightAuctionRound = roundList.get(i);

            if (date.after(copyrightAuctionRound.getRoundEndTime())) {
                //本轮最高价大于0和不为空
                if (ObjectUtil.isNotEmpty(copyrightAuctionRound.getRoundHighestPrice()) && copyrightAuctionRound.getRoundHighestPrice() > 0) {
                    detailsVO.setStartPrice(copyrightAuctionRound.getRoundHighestPrice());
                }
            }
            Boolean nowRound = Boolean.FALSE;
            if (DateUtil.isIn(date, copyrightAuctionRound.getRoundStartTime(), copyrightAuctionRound.getRoundEndTime())) {
                isInRound = Boolean.TRUE;
                nowRound = Boolean.TRUE;
                roundId = copyrightAuctionRound.getId();

            }

            //如果是第一轮
//            if (i == 0) {
//                CopyrightMarketAuctionFlowDTO copyrightMarketAuctionFlowDTO = new CopyrightMarketAuctionFlowDTO();
//                copyrightMarketAuctionFlowDTO.setTime(DateUtil.format(copyrightAuctionRound.getRoundStartTime(), "MM-dd HH:mm"));
//            }

            CopyrightMarketAuctionFlowDTO copyrightMarketAuctionFlowDTO = new CopyrightMarketAuctionFlowDTO();
            String time = DateUtil.format(copyrightAuctionRound.getRoundStartTime(), "HH:mm") + "-" + DateUtil.format(copyrightAuctionRound.getRoundEndTime(), "HH:mm");
            copyrightMarketAuctionFlowDTO.setTime(time);
            copyrightMarketAuctionFlowDTO.setId(copyrightAuctionRound.getId());
            copyrightMarketAuctionFlowDTO.setNowRound(nowRound);
            copyrightMarketAuctionFlowDTO.setRoundStartTime(copyrightAuctionRound.getRoundStartTime());
            copyrightMarketAuctionFlowDTO.setRoundEndTime(copyrightAuctionRound.getRoundEndTime());

            //如果不是最后一轮
            if (date.before(copyrightAuctionRound.getRoundStartTime()) && Objects.isNull(detailsVO.getNextRoundTime())) {
                detailsVO.setNextRoundTime(copyrightAuctionRound.getRoundStartTime());
            }
            copyrightMarketAuctionFlowDTOS.add(copyrightMarketAuctionFlowDTO);
            //如果是最后一轮
//            if (i == roundList.size() - 1) {
//                CopyrightMarketAuctionFlowDTO copyrightMarketAuctionFlowEndDTO = new CopyrightMarketAuctionFlowDTO();
//                copyrightMarketAuctionFlowEndDTO.setTime(DateUtil.format(copyrightAuctionRound.getRoundEndTime(), "MM-dd HH:mm"));
//            }
        }
        detailsVO.setAuctionProcess(copyrightMarketAuctionFlowDTOS);
        detailsVO.setIsInRound(isInRound);
        detailsVO.setRoundBidCount(0);
        detailsVO.setDrawPrize(Boolean.FALSE);
        if (date.after(copyrightAuctionRecord.getAuctionEndTime())) {
            detailsVO.setDrawPrize(copyrightAuctionRecord.getHaveResult());
        }
        Boolean auctionFirstParticipation = Boolean.FALSE;
        if (roundId != 0L) {
            //查询用户当前轮投入数量
            CopyrightAuctionUserBidding userBidding = copyrightAuctionUserBiddingDao.sumByRoundIdAndUserId(copyrightAuctionRecord.getId(), roundId, user.getId());
            if (Objects.nonNull(userBidding) && userBidding.getBiddingNum() > 0) {
                detailsVO.setRoundBidCount(userBidding.getBiddingNum());
                auctionFirstParticipation = Boolean.TRUE;
            }
        }
        detailsVO.setAuctionFirstParticipation(auctionFirstParticipation);
        return detailsVO;
    }

    /**
     * 市场版权拍卖用户出价
     *
     * @param auctionBidDTO
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void marketBid(CopyrightMarketAuctionBidDTO auctionBidDTO, UserInfo user) {
        Date date = new Date();
        CopyrightAuctionRecord copyrightAuctionRecord = copyrightAuctionRecordDao.getById(auctionBidDTO.getId());
        Assert.notNull(copyrightAuctionRecord, () -> new GlobalRunTimeException("拍卖活动不存在"));
        CopyrightAuction copyrightAuction = copyrightAuctionDao.getByCollectionId(copyrightAuctionRecord.getCollectionId());
        Assert.notNull(copyrightAuction, () -> new GlobalRunTimeException("拍卖活动不存在"));
        Assert.isTrue(copyrightAuction.getStatus(), () -> new GlobalRunTimeException("拍卖活动未开启"));
        Assert.isTrue(date.before(copyrightAuctionRecord.getAuctionEndTime()), () -> new GlobalRunTimeException("活动已结束"));
        //查询轮次
        CopyrightAuctionRound copyrightAuctionRound = copyrightAuctionRoundDao.getById(auctionBidDTO.getRoundId());
        if (!DateUtil.isIn(date, copyrightAuctionRound.getRoundStartTime(), copyrightAuctionRound.getRoundEndTime())) {
            //本轮暂未开始或已结束
            throw new GlobalRunTimeException("本轮暂未开始或已结束");
        }

        //查询用户当前轮是否已经投入
        Boolean hasBid = Boolean.FALSE;
        Integer lastHighPrice = copyrightAuctionRecord.getStartPrice();
        Integer count = copyrightAuctionUserBiddingDao.countByRoundIdAndUserId(copyrightAuctionRecord.getId(), auctionBidDTO.getRoundId(), user.getId());
        if (count > 0) {
            hasBid = Boolean.TRUE;
        }
        if (copyrightAuctionRound.getRound() > 1) {
            CopyrightAuctionRound lastCopyrightAuctionRound = copyrightAuctionRoundDao.getLastRound(copyrightAuctionRecord.getId(), copyrightAuctionRound.getRound() - 1);
            if (!lastCopyrightAuctionRound.getFinish()) {
                throw new GlobalRunTimeException("数据处理中请稍后再试");
            }
            if (Objects.nonNull(lastCopyrightAuctionRound.getRoundHighestPrice()) && lastCopyrightAuctionRound.getRoundHighestPrice() > 0) {
                lastHighPrice = lastCopyrightAuctionRound.getRoundHighestPrice();
            }
        }
        CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
        //如果已经投入
        if (hasBid) {
            //判断auctionBidDTO中的bidNum是否是auctionConfig中的priceAmplitude整数倍
            if (auctionBidDTO.getBidNum() % auctionConfig.getPriceAmplitude() != 0) {
                throw new GlobalRunTimeException("出价必须是" + auctionConfig.getPriceAmplitude() + "的整数倍");
            }
        } else {
            if (auctionBidDTO.getBidNum() < lastHighPrice) {
                throw new GlobalRunTimeException("最低出价必须大于" + lastHighPrice);
            }
            //投入数量 - 上次最高 是否是auctionConfig中的priceAmplitude整数倍
            if ((auctionBidDTO.getBidNum() - lastHighPrice) % auctionConfig.getPriceAmplitude() != 0) {
                throw new GlobalRunTimeException("出价数量错误");
            }
        }
        //判断是否已经结束
        StaticData scrollPropsId = staticDataDao.getByType("scroll_props_id");
        Long equityId = Long.parseLong(scrollPropsId.getValue());
        EquityProps equityProps = equityPropsService.getById(equityId);
        CopyrightAuctionUserBidding copyrightAuctionUserBidding = copyrightAuctionUserBiddingDao.getByRecordIdAndRoundIdAndUserId(copyrightAuctionRecord.getId(), copyrightAuctionRound.getId(), user.getId());
        //用户本轮是否有投入
        Long bidId = 0L;
        if (ObjectUtil.isEmpty(copyrightAuctionUserBidding)) {
            copyrightAuctionUserBidding = new CopyrightAuctionUserBidding();
            copyrightAuctionUserBidding.setCopyrightAuctionRecordId(copyrightAuctionRecord.getId());
            copyrightAuctionUserBidding.setCopyrightAuctionRoundId(copyrightAuctionRound.getId());
            copyrightAuctionUserBidding.setUserId(user.getId());
            copyrightAuctionUserBidding.setBiddingNum(auctionBidDTO.getBidNum());
            copyrightAuctionUserBidding.setFirstTitle(equityProps.getFirstTitle());
            copyrightAuctionUserBidding.setStatus(CopyrightCollectionStatusEnum.UNDER_PLEDGE);
            copyrightAuctionUserBidding.setBidTime(date);
            Assert.isTrue(copyrightAuctionUserBiddingDao.save(copyrightAuctionUserBidding), () -> new GlobalRunTimeException("出价失败,请稍后重试!"));
            bidId = copyrightAuctionUserBidding.getId();
        } else {
            bidId = copyrightAuctionUserBidding.getId();
            copyrightAuctionUserBidding.setBiddingNum(copyrightAuctionUserBidding.getBiddingNum() + auctionBidDTO.getBidNum());
            Assert.isTrue(copyrightAuctionUserBiddingDao.updateBiddingNum(copyrightAuctionUserBidding.getBiddingNum(), bidId, date), () -> new GlobalRunTimeException("出价失败,请稍后重试!"));
        }
        //冻结资产
        List<UserEquityProps> userEquityPropsList = userEquityPropsService.getHavingListByUserIdAndEquityPropsIdAndLimit(user.getId(), equityId, auctionBidDTO.getBidNum());
        if (CollUtil.isEmpty(userEquityPropsList) || userEquityPropsList.size() < auctionBidDTO.getBidNum()) {
            throw new GlobalRunTimeException("可用道具数量不足");
        }
        Assert.isTrue(userEquityPropsService.updateHoldStatusBatchById(userEquityPropsList.stream().map(UserEquityProps::getId).collect(Collectors.toList()), UserEquityPropsHoldingStatusEnum.AUCTION_LOCK, UserEquityPropsHoldingStatusEnum.NORMAL), () -> new GlobalRunTimeException("权益道具锁定失败"));
        List<CopyrightAuctionUserBiddingDetail> saveDetailsList = new ArrayList<>();
        for (UserEquityProps userEquityProps : userEquityPropsList) {
            CopyrightAuctionUserBiddingDetail auctionUserBiddingDetail = new CopyrightAuctionUserBiddingDetail();
            auctionUserBiddingDetail.setCopyrightAuctionRecordId(copyrightAuctionRecord.getId());
            auctionUserBiddingDetail.setCopyrightAuctionUserBiddingId(bidId);
            auctionUserBiddingDetail.setUserId(user.getId());
            auctionUserBiddingDetail.setRelationId(userEquityProps.getId());
            saveDetailsList.add(auctionUserBiddingDetail);
        }
        Assert.isTrue(copyrightAuctionUserBiddingDetailDao.saveList(saveDetailsList), () -> new GlobalRunTimeException("出价失败,请稍后重试!"));
        //生成biddingLog
        CopyrightAuctionUserBiddingLog copyrightAuctionBiddingLog = new CopyrightAuctionUserBiddingLog();
        copyrightAuctionBiddingLog.setCopyrightAuctionRecordId(copyrightAuctionRecord.getId());
        copyrightAuctionBiddingLog.setCopyrightAuctionUserBiddingId(bidId);
        copyrightAuctionBiddingLog.setUserId(user.getId());
        copyrightAuctionBiddingLog.setBiddingNum(auctionBidDTO.getBidNum());
        copyrightAuctionBiddingLog.setFirstTitle(copyrightAuctionUserBidding.getFirstTitle());
        Assert.isTrue(copyrightAuctionUserBiddingLogDao.save(copyrightAuctionBiddingLog), () -> new GlobalRunTimeException("出价失败,请稍后重试!"));
    }


    /**
     * 结果公示
     *
     * @param id
     * @return
     */
    @Override
    public List<CopyrightAuctionWinListVO> auctionWinList(Long id) {
        CopyrightAuctionRecord copyrightAuctionRecord = copyrightAuctionRecordDao.getById(id);
        Assert.isTrue(copyrightAuctionRecord.getHaveResult(), () -> new GlobalRunTimeException("未开奖"));
        return copyrightAuctionRoundDao.auctionWinList(id);
    }

    /**
     * 搜索
     *
     * @param name
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public IPage<CopyrightMarketAuctionDTO> marketSearch(String name, Integer pageNo, Integer pageSize) {
        IPage<CopyrightMarketAuctionDTO> auctionDTOIPage = copyrightAuctionRecordDao.market(pageNo, pageSize, name);
//        if (Objects.nonNull(auctionDTOIPage) && !CollectionUtils.isEmpty(auctionDTOIPage.getRecords())) {
//            CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
//            for (CopyrightMarketAuctionDTO record : auctionDTOIPage.getRecords()) {
//                Integer mapProsperity = nftRegionBindingService.getMapProsperity(record.getCollectionId());
//                record.setProsperity(auctionConfig.getProsperityRate().multiply(BigDecimal.valueOf(mapProsperity)).setScale(2,RoundingMode.DOWN));
//            }
//        }
        return auctionDTOIPage;
    }

    /**
     * 市场版权拍卖开启时间
     *
     * @return
     */
    @Override
    public CopyrightAuctionOpenTimeVO marketOpenTime() {
        CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
        CopyrightAuctionOpenTimeVO copyrightAuctionOpenTimeVO = new CopyrightAuctionOpenTimeVO();
        copyrightAuctionOpenTimeVO.setStartTime(DateUtil.format(auctionConfig.getAuctionStartTime(), "HH:mm"));
        copyrightAuctionOpenTimeVO.setEndTime(DateUtil.format(auctionConfig.getAuctionEndTime(), "HH:mm"));
        return copyrightAuctionOpenTimeVO;
    }

    /**
     * 本轮最高生成下一轮起拍价
     *
     * @param currentRound
     * @param nextRound
     * @param num
     * @param userId
     */
    @Override
    public void generateNextStartPrice(CopyrightAuctionRound currentRound, CopyrightAuctionRound nextRound, Integer num, Long userId, List<Long> userEquityPropsIdList) {
        CopyrightAuctionUserBidding nowBidding = copyrightAuctionUserBiddingDao.getByRecordIdAndRoundIdAndUserId(currentRound.getCopyrightAuctionRecordId(), currentRound.getId(), userId);
        if (Objects.isNull(nowBidding)) {
            return;
        }
        Assert.isTrue(copyrightAuctionUserBiddingDao.updateStatusById(nowBidding.getId(), CopyrightCollectionStatusEnum.HAS_RELEASED), () -> new GlobalRunTimeException("释放失败"));
        CopyrightAuctionUserBidding copyrightAuctionUserBidding = new CopyrightAuctionUserBidding();
        copyrightAuctionUserBidding.setCopyrightAuctionRecordId(currentRound.getCopyrightAuctionRecordId());
        copyrightAuctionUserBidding.setCopyrightAuctionRoundId(nextRound.getId());
        copyrightAuctionUserBidding.setUserId(userId);
        copyrightAuctionUserBidding.setBiddingNum(num);
        copyrightAuctionUserBidding.setFirstTitle(nowBidding.getFirstTitle());
        copyrightAuctionUserBidding.setStatus(CopyrightCollectionStatusEnum.UNDER_PLEDGE);
        copyrightAuctionUserBidding.setBidTime(new Date());
        Assert.isTrue(copyrightAuctionUserBiddingDao.save(copyrightAuctionUserBidding), () -> new GlobalRunTimeException("释放后插入投入总数量失败!"));

        List<CopyrightAuctionUserBiddingDetail> saveDetailsList = new ArrayList<>();
        for (Long id : userEquityPropsIdList) {
            CopyrightAuctionUserBiddingDetail auctionUserBiddingDetail = new CopyrightAuctionUserBiddingDetail();
            auctionUserBiddingDetail.setCopyrightAuctionRecordId(currentRound.getCopyrightAuctionRecordId());
            auctionUserBiddingDetail.setCopyrightAuctionUserBiddingId(copyrightAuctionUserBidding.getId());
            auctionUserBiddingDetail.setUserId(userId);
            auctionUserBiddingDetail.setRelationId(id);
            saveDetailsList.add(auctionUserBiddingDetail);
        }
        Assert.isTrue(copyrightAuctionUserBiddingDetailDao.saveList(saveDetailsList), () -> new GlobalRunTimeException("释放后插入具体投入总数量失败"));
        //生成biddingLog
        CopyrightAuctionUserBiddingLog copyrightAuctionBiddingLog = new CopyrightAuctionUserBiddingLog();
        copyrightAuctionBiddingLog.setCopyrightAuctionRecordId(currentRound.getCopyrightAuctionRecordId());
        copyrightAuctionBiddingLog.setCopyrightAuctionUserBiddingId(copyrightAuctionUserBidding.getId());
        copyrightAuctionBiddingLog.setUserId(userId);
        copyrightAuctionBiddingLog.setBiddingNum(num);
        copyrightAuctionBiddingLog.setFirstTitle(copyrightAuctionUserBidding.getFirstTitle());
        Assert.isTrue(copyrightAuctionUserBiddingLogDao.save(copyrightAuctionBiddingLog), () -> new GlobalRunTimeException("释放后插入每次投入总数量失败!"));
    }


    /**
     * 获取用户协议
     *
     * @return
     */
    @Override
    public String auctionGetRule() {
        return staticDataDao.getByType("second_auction_bid_img").getValue();
    }

    /**
     * 用户是否同意协议
     *
     * @param id
     */
    @Override
    public Boolean userAgreement(Long id) {
        int count = copyrightAuctionUserAgreementDao.countByUserId(id);
        return count > 0;
    }

    /**
     * 用户同意协议
     *
     * @param id
     */
    @Override
    public void auctionUserAgreement(Long id) {
        CopyrightAuctionUserAgreement copyrightAuctionUserAgreement = new CopyrightAuctionUserAgreement();
        copyrightAuctionUserAgreement.setUserId(id);
        copyrightAuctionUserAgreementDao.save(copyrightAuctionUserAgreement);
    }

    /**
     * 修改起拍价
     * @param copyrightAuctionAdminDTO
     */
   /* @Override
    public void collectionUpdateStartPrice(CopyrightAuctionUpdateStartPriceAdminDTO copyrightAuctionAdminDTO) {
        CopyrightAuction copyrightAuction = copyrightAuctionDao.getById(copyrightAuctionAdminDTO.getId());
        if (Objects.isNull(copyrightAuction)) {
            throw new GlobalRunTimeException("拍卖不存在");
        }
        Assert.isTrue(
                copyrightAuctionDao.updateStartPrice(copyrightAuctionAdminDTO.getId(), copyrightAuctionAdminDTO.getStartPrice()), () -> new GlobalRunTimeException("操作失败,请稍后重试!"));

    }*/

    /**
     * 平台用户分成
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void platformDividends() {
        RLock lock = redisson.getLock(RedisKeyEnum.SECOND_BID_USER_DIVIDENDS.getKey());
        try {
            boolean res = lock.tryLock(3, TimeUnit.SECONDS);
            if (!res) {
                throw new GlobalException("拍卖处理中！！！！");
            }
            CopyrightAuctionConfig auctionConfig = copyrightAuctionConfigDao.getNewOne();
            if (Objects.isNull(auctionConfig)) {
                throw new GlobalRunTimeException("二级拍卖平台用户分成处理拍卖配置为空");
            }
            List<CopyrightAuctionDividedLog> resultList = copyrightAuctionDividedLogDao.getPlatFormDividends();
            if (CollectionUtils.isEmpty(resultList)) {
                return;
            }
            List<Long> resultIdList = resultList.stream().map(CopyrightAuctionDividedLog::getId).collect(Collectors.toList());
            //查询需要分账那些用户
            List<NftRegionBindingUserVO> nftRegionBindingUserVOS = nftRegionBindingService.listBindUserId();
            if (CollectionUtils.isEmpty(nftRegionBindingUserVOS)) {
                //直接更新为已结算
                Assert.isTrue(copyrightAuctionDividedLogDao.updateStatusByIdList(resultIdList, Boolean.TRUE), () -> new GlobalRunTimeException("拍卖平台用户分成失败"));
                return;
            }
            //需要分账的数据数量
            int sum = resultList.stream().mapToInt(CopyrightAuctionDividedLog::getNum).sum();
            if (sum <= 0) {
                //直接更新为已结算
                Assert.isTrue(copyrightAuctionDividedLogDao.updateStatusByIdList(resultIdList, Boolean.TRUE), () -> new GlobalRunTimeException("拍卖平台用户分成失败"));
                return;
            }
            //平台分成
            BigDecimal serviceFeeRate = auctionConfig.getServiceFeeRate();
            //使用sum * (serviceFeeRate / 100)
            BigDecimal serviceFee = serviceFeeRate.divide(new BigDecimal("100"), 2, RoundingMode.DOWN).multiply(BigDecimal.valueOf(sum)).setScale(2, RoundingMode.DOWN);
            //将serviceFee改为int
            int serviceFeeInt = serviceFee.intValue();
            if (serviceFeeInt <= 1) {
                //直接更新为已结算
                Assert.isTrue(copyrightAuctionDividedLogDao.updateStatusByIdList(resultIdList, Boolean.TRUE), () -> new GlobalRunTimeException("拍卖平台用户分成失败"));
                return;
            }
            //用户平均分的数量
            int average = serviceFeeInt / nftRegionBindingUserVOS.size();
            if (average <= 0) {
                //直接更新为已结算
                Assert.isTrue(copyrightAuctionDividedLogDao.updateStatusByIdList(resultIdList, Boolean.TRUE), () -> new GlobalRunTimeException("拍卖平台用户分成失败"));
                return;
            }
            Map<Long, List<NftRegionBindingUserVO>> binddMap = nftRegionBindingUserVOS.stream().collect(Collectors.groupingBy(NftRegionBindingUserVO::getUserId));
            Map<Long, Integer> addNum = new HashMap<>();
            for (Long userId : binddMap.keySet()) {
                addNum.put(userId, binddMap.get(userId).size() * average);
            }
            StaticData scrollPropsId = staticDataDao.getByType("scroll_props_id");
            Long equityId = Long.parseLong(scrollPropsId.getValue());
            EquityProps equityProps = equityPropsService.getById(equityId);
            userEquityPropsService.disposalOfAuctionItems(addNum, equityProps);
            //直接更新为已结算
            Assert.isTrue(copyrightAuctionDividedLogDao.updateStatusByIdList(resultIdList, Boolean.TRUE), () -> new GlobalRunTimeException("拍卖平台用户分成失败"));
        } catch (Exception e) {
            WeChatUtil.sendLiGenWeChatMessage(StrUtil.format("拍卖处理失败 ,异常:{}", e.getMessage()));
            log.error("拍卖平台用户分成失败,异常:{}", e.getMessage());
            throw new GlobalRunTimeException(e.getMessage());
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}